<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
    <meta charset="utf-8">
    <meta http-equiv="pragma" content="no-cache" />

    <title>RoadScanner</title>
    
    <style>

        html {
            position: relative;
            min-height: 100%;
        }
        body {
            margin: 0px;
            background: Gray;
            padding: 1px;
        }

        .container {
            border: solid Black 1px;  
            position: absolute;  
            padding: 5px;            
        }

        #left {
            background: LightYellow;
            top:0px;
            bottom:0px;
            left:0px;
            width:200px;
        }

        #main {
            background: SkyBlue;
            top: 0px;
            bottom: 0px;
            left: 0px;
            right:0px;
        }

        #map-canvas {
            position: relative;
            height: 100%; 
            width: 100%;           
        }

    </style>

    <script src="https://maps.googleapis.com/maps/api/js?v=3.exp"></script>

    <script>
        
        function doConnect() {
            websocket = new WebSocket("ws://localhost:8000/");
            websocket.binaryType = 'arraybuffer';
            websocket.onopen = function(event) { onOpen(event) };
            websocket.onclose = function(event) { onClose(event) };
            websocket.onmessage = function(event) { onMessage(event) };
            websocket.onerror = function(event) { onError(event) };
        }

        function doDisconnect() {
            websocket.close();
        }        


        function onOpen(event) {
            console.log("connected");
        }

        function onClose(event) {
            console.log("disconnected");
        }

        function onMessage(event) {
            var roadArray = new Int32Array(event.data);
            //console.log(res);
            addRoadToMap(roadArray);
        }

        function onError(event) {
            console.log('error: ' + event.data);
            websocket.close();
        }


        function Send(message) {
            websocket.send(message);
        }

    </script>

    <script>

        var map;
        var dService;
        var dRenderer;

        var polyline = [];        
        var start;
        var end;

        function initialize() {

            // Map
            var mapOptions = {                
                mapTypeId: google.maps.MapTypeId.HYBRID,
                center: {lat: -30, lng: -51.2},
                zoom: 7
            };
            map = new google.maps.Map(document.getElementById('map-canvas'), 
                mapOptions);


            
            var layer_relevo = new google.maps.GroundOverlay(
                'overlay.jpg',
                new google.maps.LatLngBounds(
                    new google.maps.LatLng(-31.7534721,-52.9564534),
                    new google.maps.LatLng(-30.0481394,-51.3321098)),
                {
                    clickable: false,
                    opacity: 0.4,
            });

            layer_relevo.setMap(map);
            


            // Service
            dService =  new google.maps.DirectionsService();        

            // Renderer
            dRenderer = new google.maps.DirectionsRenderer(
            {
                draggable: true
            });

            dRenderer.setMap(map);


            // Events
            google.maps.event.addListener(map, "click", function(event)
            {
                click(event.latLng);
            });    

            google.maps.event.addListener(dRenderer, "directions_changed", function(event)
            {
                updatePolyline();
            });     


            doConnect();       

        }


        function click(location) {
            console.log("clicked")

            if (typeof start == 'undefined') {
                start = location;
                return;
            }

            else
            if (typeof end == 'undefined') {
                end = location;
                console.log("clicked second point")
                calcRoute();
            }            
            else
            {
                calcRoute();
            }
        }   



        function calcRoute() {

            var request = {
                origin:start,
                destination:end,
                travelMode: google.maps.TravelMode.DRIVING,
                provideRouteAlternatives : false
            };

            dService.route(request, function(dResult, status) {
                if (status == google.maps.DirectionsStatus.OK) {                    
                    dRenderer.setDirections(dResult);
                }
            });
        }


        function updatePolyline()
        {
            coordinates = [];

            var route = dRenderer.getDirections().routes[0];
            var legs = route.legs

            console.log("legs " + legs.length)

            for (var i = 0; i < legs.length; i++)
            {
                var leg = legs[i];
                var steps = leg.steps;

                console.log("steps " + steps.length)

                var startIndex = i == 0 ? 0 : 1

                for (var j = startIndex; j < steps.length; j++)
                {
                    var step = steps[j];
                    var points = step.polyline.points

                    var decodedCoords = decodePolyline(points);

                    if (j > 0) {
                        decodedCoords.shift();
                    }

                    coordinates.push.apply(coordinates, decodedCoords);
                }
            }

            // need to remove endpoints and duplicated consecutive points
            coordinates = coordinates
                .filter(function(item, pos, arr){
                    return pos === 0 || item !== arr[pos-1]
                })
                .slice(1, coordinates.length -1);

            addPolylineToMap(coordinates);

            var message = lineString(coordinates);

            console.log(message);

            //alert(message);

            Send(message);
        }


        function decodePolyline(str) {
            var index = 0,
            lat = 0,
            lng = 0,
            coordinates = [],
            shift = 0,
            result = 0,
            byte = null,
            latitude_change,
            longitude_change

            while (index < str.length) {

                byte = null;
                shift = 0;
                result = 0;

                do {
                    byte = str.charCodeAt(index++) - 63;
                    result |= (byte & 0x1f) << shift;
                    shift += 5;
                } while (byte >= 0x20);

                latitude_change = ((result & 1) ? ~(result >> 1) : (result >> 1));

                shift = result = 0;

                do {
                    byte = str.charCodeAt(index++) - 63;
                    result |= (byte & 0x1f) << shift;
                    shift += 5;
                } while (byte >= 0x20);

                longitude_change = ((result & 1) ? ~(result >> 1) : (result >> 1));

                lat += latitude_change;
                lng += longitude_change;

                coordinates.push([lat, lng]);
            }

            return coordinates;
        }; 


        function addPolylineToMap(coordinates) {

            var latlngs = [];
            for (var i = 0; i < coordinates.length; i++) {
                var c = coordinates[i];
                latlngs.push({lat: c[0]*1e-5, lng: c[1]*1e-5})
            }

            var polyline = new google.maps.Polyline({
                path: latlngs,
                geodesic: true,
                strokeColor: '#FF0000',
                strokeOpacity: 0.5,
                strokeWeight: 2
            });

            polyline.setMap(map);            
        }

        function addRoadToMap(array) { 
            var latlngs = []
            
            var len = array.length;
            for (var i = 0; i < len; i += 2) {
                var lon = array[i];
                var lat = array[i + 1];
                latlngs.push({lat:lat*1e-5, lng:lon*1e-5})
            };

            var polyline = new google.maps.Polyline({
                path: latlngs,
                geodesic: true,
                strokeColor: '#FF8800',
                strokeWeight: 2
            });

            polyline.setMap(map);              

            /* 
            var icon = {
                path: google.maps.SymbolPath.CIRCLE,
                strokeColor: "#0088FF",
                strokeWeight: 1,
                scale: 2
            };

            var start = new google.maps.Marker({
                position: latlngs[0],
                icon: icon,
                map: map
            });

            var end = new google.maps.Marker({
                position: latlngs[latlngs.length-1],
                icon: icon,
                map: map
            });
            */

        }

        function lineString(coordinates)     
        {
            var coords = [];
            for (var i = 0; i < coordinates.length; i++)
            {
                var c = coordinates[i];
                coords.push([c[1], c[0]]);
            }
            return coords.join(" ");
        }

        google.maps.event.addDomListener(window, 'load', initialize);

    </script>
</head>

<body>
<!--
    <div id="left" class="container">
        <form title="Controles">

        </form>
    </div>
-->
    <div id="main" class="container">
        <div id="map-canvas"></div>
    </div>

</body>
</html>
